#include "fsm.h"
#include <stdio.h>
#include "hal_tty.h"
#include "fsm_defs.h"
#include "FreeRTOS.h"
#include "task.h"

int fsm_init(fsm_object_t *fsm,int init,fsm_table_t *table,int table_count) {
	
	fsm->prev_state = init;
	fsm->cur_state = init;
	fsm->fsm_table = table;
	fsm->init_state = init;
	//fsm->fsm_nodes = states;
	fsm->table_count = table_count;
	//g_tty_.printf("table count : %d \r\n",table_count);
	return 0;
}

void fsm_state_transfer(fsm_object_t *fsm,int state) {
	
	fsm->prev_state = fsm->cur_state;
	fsm->cur_state = state;
	
	//g_tty_.printf("cur state ; %d next state : %d \r\n",fsm->cur_state,state);
}

int fsm_event_once(fsm_object_t *fsm,int event) {
	
	fsm_table_t *table = fsm->fsm_table;
	int cur_state = fsm->cur_state;
	fsm_table_t *change_table = NULL;
	int ret = FSM_EVENT_NO_SIG;
	for(int i = 0; i < fsm->table_count;i++) {
		if(table[i].cur_state == cur_state) {
			uint8_t transfer_enable = 0;
				if(table[i].event != event) {
					if(table[i].event == TMODE_EVENT_CLICK_ANY) {
						if(event > TMODE_EVENT_CLICK_ANY || event < TMODE_EVENT_TEST_MIN)
							continue;	
					} else if(table[i].event == TMODE_EVENT_KEY_ANY) {
						if(event > TMODE_EVENT_KEY_ANY || event < TMODE_EVENT_TEST_MIN)
							continue;	
					} else if(table[i].event == FAULT_EVENT_ANY) {
							continue;	
					} else {
						continue;
					}
				}
				
			//if(fsm->cur_state_ptr.exit)
			//	fsm->fsm_nodes[cur_state].exit();
				
			change_table = &table[i];
			if(change_table->event_call) 
				ret = change_table->event_call(event);
			
			
			//g_tty_.printf("table[%d]: %d %d %d \r\n",i,event,cur_state,change_table->next_state);
			fsm_state_transfer(fsm,change_table->next_state);
			
			// if(fsm->cur_state_ptr.init)
			// 	fsm->fsm_nodes[cur_state].init();
			break;
		}
	}
	return ret;
}

int fsm_event_handle(fsm_object_t *fsm,int event) {
	
	vTaskSuspendAll();

	uint8_t loop = fsm_event_once(fsm,event);
	while(loop != FSM_EVENT_RUNNING && loop != FSM_EVENT_NO_SIG) {
		loop = fsm_event_once(fsm,loop);
		//g_tty_.printf(" loop : %d \r\n",loop);
	}
	
	xTaskResumeAll();
	return loop;
}


